﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DotNET4Study
{
    //说明：本代码为协变逆变的演示
    public static class ConvariantContravariant
    {
        public static void Excute()
        {
            //1.类型本身 子类的实例可以替代父类实例
            Person p = new Student();

            //2.委托内的类型 可以进行转换
            InputDelegate myDelegate= new InputDelegate(InMethod);
            myDelegate(new Student());

            ////3.泛型类内的类型 不能进行转换
            //List<Person> list = new List<Student>();

            ////4.泛型委托内的类型 不可以直接进行转换（这样就违反了原则，使用父类实例代替子类实例了）
            //InputDelegate<Person> pDelegate = new InputDelegate<Student>(MyMethod);
            //pDelegate(new Person());

            //InputDelegate<Person> pDelegate = new InputDelegate<Person>(InMethod);
            //InputDelegate<Student> sDelegate = pDelegate;
            //sDelegate(new Student());
            //pDelegate(new Student());

            InputDelegate<Student> sDelegate = new InputDelegate<Person>(InMethod);
            sDelegate(new Student());
            //sDelegate(new Person());


            //OutDelegate<Person> opDelegate = new OutDelegate<Person>(OutMethod);
            //OutDelegate<Student> osDelegate = new OutDelegate<Student>(OutMethod);
            //opDelegate = osDelegate;
            OutDelegate<Person> opDelegate = new OutDelegate<Student>(OutMethod);
            opDelegate();
        }

        private static void InMethod(Person p)
        {
            Console.WriteLine(p.Name);
        }

        private static Student OutMethod()
        {
            return new Student();
        }
    }

    //以下是一个使用的自定义委托
    public delegate void InputDelegate(Person p);
    public delegate void InputDelegate<in T>(T t);
    
    public delegate Person OutDelegate();
    public delegate T OutDelegate<out T>();
}

